﻿#region Copyright(C) 2018 FI Ltd. All rights reserved.
// ==================================================================================================
// Copyright(C) 2018 FI Ltd. All rights reserved.
//
// SYSTEM NAME	    : FI.Net Application Framework
// COMPONENT ID	    : FI.Core
// COMPONENT DESC   : FI.Net Core Foundation
//
// CREATED DATE/BY  : 18 Aug 2018 / Tian Mi
//
// REVISION HISTORY :	
// DATE/BY			SR#/CS/PM#/OTHERS		DESCRIPTION OF CHANGE
// ==================================================================================================
#endregion

using FI.Core.Configuration;
using FI.Core.Properties;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Reflection;
using System.Linq;
using FI.Core.IoC;

namespace FI.Core.Caching.Configuration
{
    /// <summary>
    /// This is base class of all concrete cache store specific configuration elements.
    /// </summary>
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "DataBase")]
    public class CacheStoreDataBase : ConfigurationElement
    {
        #region Constants
        private const string EnabledProperty            = "enabled";
        private const string PriorityProperty           = "priority";
        private const string ExpirationModeProperty     = "expirationMode";
        private const string ExpiredTimeProperty        = "expirationTime";
        private const string ExpiredTimeFormatProperty  = "expirationTimeFormat";
        private const string DepedentFileNameProperty   = "depedentFile";
        private const string PrefixPropertyName         = "prefix";
        private const string FactoryPropertyName        = "factory";
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="CacheStoreDataBase"/> is enabled.
        /// </summary>
        /// <value>
        ///   <c>true</c> if enabled; otherwise, <c>false</c>.
        /// </value>
        [ConfigurationProperty(EnabledProperty, IsRequired = false, DefaultValue = false)]
        public bool Enabled
        {
            get { return (bool)base[EnabledProperty]; }
            set { base[EnabledProperty] = value; }
        }

        /// <summary>
        /// Gets or sets the prefix of cache item key.
        /// </summary>
        /// <value>
        /// The prefix of cache item key.
        /// </value>
        [ConfigurationProperty(PrefixPropertyName, IsRequired = false, DefaultValue = "")]
        public string Prefix
        {
            get { return (string)base[PrefixPropertyName]; }
            set { base[PrefixPropertyName] = value; }
        }

        /// <summary>
        /// Gets or sets the priority of cache item to be added.
        /// </summary>
        /// <value>
        /// The priority of cache item to be added.
        /// </value>
        [ConfigurationProperty(PriorityProperty, IsRequired = false, DefaultValue = CacheItemPriority.Normal)]
        public CacheItemPriority Priority
        {
            get { return (CacheItemPriority)base[PriorityProperty]; }
            set { base[PriorityProperty] = value; }
        }

        /// <summary>
        /// Gets or sets the expiration mode of cache item.
        /// </summary>
        /// <value>
        /// The expiration mode of cache item.
        /// </value>
        [ConfigurationProperty(ExpirationModeProperty, IsRequired = false, DefaultValue = CacheItemExpirationMode.AbsoluteTime)]
        public CacheItemExpirationMode ExpirationMode
        {
            get { return (CacheItemExpirationMode)base[ExpirationModeProperty]; }
            set { base[ExpirationModeProperty] = value; }
        }

        /// <summary>
        /// Gets or sets the expired time for the two expiration modes: Absolute and Sliding.
        /// </summary>
        /// <value>
        /// The expired time for the two expiration modes: Absolute and Sliding.
        /// </value>
        [ConfigurationProperty(ExpiredTimeProperty, IsRequired = false, DefaultValue = "00:15:00")]
        public string ExpirationTime
        {
            get { return (string)base[ExpiredTimeProperty]; }
            set { base[ExpiredTimeProperty] = value; }
        }

        /// <summary>
        /// Gets or sets the expired time format for the expiration mode "TimeFormat".
        /// </summary>
        /// <value>
        /// The expired time format for the expiration mode "TimeFormat".
        /// </value>
        [ConfigurationProperty(ExpiredTimeFormatProperty, IsRequired = false, DefaultValue = "")]
        public string ExpirationTimeFormat
        {
            get { return (string)base[ExpiredTimeFormatProperty]; }
            set { base[ExpiredTimeFormatProperty] = value; }
        }

        /// <summary>
        /// Gets or sets the name of the depedent file name for the expiration mode "FileDependency".
        /// </summary>
        /// <value>
        /// The name of the depedent file name for the expiration mode "FileDependency".
        /// </value>
        [ConfigurationProperty(DepedentFileNameProperty, IsRequired = false, DefaultValue = "")]
        public string DependentFileName
        {
            get { return (string)base[DepedentFileNameProperty]; }
            set { base[DepedentFileNameProperty] = value; }
        }

        /// <summary>
        /// Gets or sets the cache store factory type.
        /// </summary>
        /// <value>
        /// The cache store factory type.
        /// </value>
        [ConfigurationProperty(FactoryPropertyName, IsRequired = false, DefaultValue = "")]
        public string Factory
        {
            get { return (string)base[FactoryPropertyName]; }
            set { base[FactoryPropertyName] = value; }
        }

        /// <summary>
        /// Gets the cache store factory.
        /// </summary>
        /// <returns>The cache store factory.</returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
        public virtual ICacheStoreFactory GetCacheStoreFactory()
        {
            if (!this.Enabled)
            {
                return new FakeCacheStoreFactory();
            }

            if (string.IsNullOrEmpty(this.Factory))
            {
                return ServiceLocatorFactory.GetServiceLocator().GetService<ICacheStoreFactory>();
            }
            else
            {
                return ServiceLocatorFactory.GetServiceLocator().GetService<ICacheStoreFactory>(this.Factory);
            }
        }

        #endregion
    }
}